﻿// ***********************************************************************
// Provided for Informational Purposes Only
//
// Apache 2.0 License
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY 
// IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR 
// PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing
// permissions and limitations under the License.
// ***********************************************************************
// Assembly  : ContractMeow.Models
// File      : Message.cs
//
// ***********************************************************************
using ContractMeow.Models.Attachments;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ContractMeow.Models
{
	public sealed class Message
	{
		public Int64 Id { get; set; }

		public Int64 ThreadId { get; set; }

		public Int64? RepliedToMessageId { get; set; }

		public User Sender { get; set; }

		// Announcements only have title.  If title is null, then not an announcement.
		private string _title;
		public string Title
		{
			get { return _title; }
			set
			{
				_title = value;
			}
		}

		public bool HasTitle
		{
			get { return !string.IsNullOrWhiteSpace(Title); }
		}

		private Uri _webUrl;
		public Uri WebUrl
		{
			get { return _webUrl; }
			set
			{
				_webUrl = value;
			}
		}

		private DateTimeOffset _postedAt;
		public DateTimeOffset PostedAt
		{
			get { return _postedAt; }
			set
			{
				_postedAt = value;
			}
		}

		private Boolean _isLiked;
		/// <summary>
		/// Denotes if the thread is liked by the current user
		/// </summary>
		public Boolean IsLiked
		{
			get { return _isLiked; }
			set
			{
				_isLiked = value;
			}
		}

		private Int32 _likeCount;
		public Int32 LikeCount
		{
			get { return _likeCount; }
			set
			{
				_likeCount = value;
			}
		}

		private String _likedByNameList;
		public String LikedByNameList
		{
			get { return _likedByNameList; }
			set
			{
				_likedByNameList = value;
			}
		}

		private List<Like> _likes;
		public List<Like> Likes
		{
			get { return _likes; }
			set
			{
				_likes = value;
			}
		}

		private String _plainTextBody;
		public String PlainTextBody
		{
			get { return _plainTextBody; }
			private set
			{
				_plainTextBody = value;
			}
		}

		private List<MessagePart> _messageParts;
		public List<MessagePart> MessageParts
		{
			get { return _messageParts; }
			set
			{
				var init = _messageParts == null && value != null;

				_messageParts = value;
				UpdatePlainTextBody();
			}
		}


		private void UpdatePlainTextBody()
		{
			if (MessageParts == null)
			{
				PlainTextBody = string.Empty;
				return;
			}

			//reset plain text body in case we modify message body more than 1 time
			PlainTextBody = string.Empty;
			foreach (var messagePart in _messageParts)
			{
				switch (messagePart.Kind)
				{
					case MessagePartType.Tag:
						PlainTextBody += "#" + messagePart.Content;
						break;
					default:
						PlainTextBody += messagePart.Content;
						break;
				}
			}
		}

		private List<IAttachmentModel> _attachments;
		public List<IAttachmentModel> Attachments
		{
			get { return _attachments; }
			set
			{
				_attachments = value;
				_fileAttachments = _attachments == null
									   ? null
									   : new List<IFileAttachmentModel>(_attachments.OfType<IFileAttachmentModel>());
				HasOtherAttachments = _attachments != null && (_attachments.OfType<IOpenGraphPageAttachmentModel>().Any() ||
															   _attachments.OfType<IMessageAttachmentModel>().Any() ||
															   _attachments.OfType<IPraiseAttachmentModel>().Any());
			}
		}

		private List<IFileAttachmentModel> _fileAttachments;
		public List<IFileAttachmentModel> FileAttachments
		{
			get { return _fileAttachments; }
		}

		public Boolean HasAttachments
		{
			get { return _attachments != null && _attachments.Any(); }
		}

		public Boolean HasFileAttachments
		{
			get { return _fileAttachments != null && _fileAttachments.Any(); }
		}

		public bool HasOtherAttachments { get; set; }

		public bool HasMultipleAttachments
		{
			get
			{
				return HasAttachments && _attachments.Count > 1;
			}
		}

		private List<Int64> _ccUserIds;
		public List<Int64> CcUserIds
		{
			get { return _ccUserIds; }
			set
			{
				_ccUserIds = value;
			}
		}
	}
}